/**
 * 
 */
package com.app.framework.http;

import java.io.Serializable;
import java.lang.reflect.Method;

import org.apache.log4j.Logger;

import com.app.framework.config.GameConfig;
import com.app.framework.config.ServiceConfig;
import com.app.framework.config.ServiceConfigLoader;
import com.app.framework.context.AbstractContext;
import com.app.framework.context.ActionRequest;
import com.app.framework.context.Context;
import com.app.framework.context.Request;
import com.app.framework.exception.ClientException;
import com.app.framework.result.RequestResult;
import com.app.framework.service.GameService;
import com.app.framework.singleton.ActionSingletonManager;
import com.app.framework.singleton.ServiceSingletonManager;
import com.app.framework.util.ErrorCodeConstants;
import com.app.service.action.HttpAction;

/**
 * @author lisong
 * @version 2013-3-7 下午3:51:21
 */
public class HttpContext extends AbstractContext {

	private static final Logger logger = Logger.getLogger(HttpContext.class);
	
	public HttpContext(HttpResponse response) {
		
		super(response, Context.TRANS_PROTO_HTTP);
		
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public RequestResult<? extends Serializable> doExecute() throws Exception {
		
		RequestResult<? extends Serializable> result = null;
		
		Request request = response.getRequest();
		
		if(request.getType() == ActionRequest.TYPE ) {//actionService-执行action
	
			ActionRequest actionRequest = (ActionRequest)request;
			
			short actionId = actionRequest.getActionId();
			
			HttpAction action = (HttpAction) ActionSingletonManager.getInstance().getSingleton(actionId);
			
			if(action == null) {
				throw new ClientException("action not exist actionId:"+actionId,ErrorCodeConstants.CLIENT_ERROR_ACTION_NAME_NOT_EXIST);
			}
			
			try {
				result = action.execute(this);
			}catch (Exception e) {
				logger.error(e);
				e.printStackTrace();
				result = RequestResult.serverException(e);
				perssistenceSession.close();//不保存数据
			}finally {
				//记录行为日志
			}
		}
		else {//自定义service
	
			short serviceId = ((HttpServiceRequest)request).getServiceId();
			
			GameService service = ServiceSingletonManager.getInstance().getSingleton(serviceId);
			
			if(service == null) {
				throw new ClientException("service not exist serviceId:"+serviceId,ErrorCodeConstants.CLIENT_ERROR_SERVICE_NAME_NOT_EXIST);
			}
			String methodName = ((HttpServiceRequest)request).getMethodName();

			GameConfig<GameService> config = ServiceConfigLoader.getInstance().getConfig(String.valueOf(serviceId));
			
			Method method = ((ServiceConfig)config).getMethods().get(methodName);
			
			if(method == null) {
				throw new ClientException("methodName not exist methodName:"+methodName,ErrorCodeConstants.CLIENT_ERROR_SERVICE_METHOD_NAME_NOT_EXIST);
			}
			try {
				result = (RequestResult<Serializable>) method.invoke(service,this);
			} catch (Exception e) {
				logger.error(e);
				e.printStackTrace();
				perssistenceSession.close();
				result = RequestResult.serverException(e);
			}
		}
		
		return result;
	}
	
	public HttpResponse getResponse() {
		return (HttpResponse) response;
	}
	
	public long getUserId() {
		if(getRequest() instanceof ActionRequest) {
			return ((ActionRequest)getRequest()).getUserId();
		}
		throw new UnsupportedOperationException();
	}
}
